package com.jplus.core.core.beans;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
//import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.jplus.core.anno.com.Scope.EScope;
import com.jplus.core.core.events.ApplicationEvent;
import com.jplus.core.core.proxys.Proxy;
import com.jplus.core.fault.InitializationError;

/**
 * Bean定义【核心】
 */
public class BeanDefinition implements Comparable<BeanDefinition> {

	public BeanDefinition(BeanKey beanKey) {
		this.beanKey = beanKey;
	}

	private BeanKey beanKey;
	// =================================
	// Bean作用域
	private EScope scope;
	// 是否延迟加载实例
	private boolean isLazyInit;
	// 是否有事务
	private boolean isTransaction;
	// 是否是Action[剥离到mvc里面去了]
	// private boolean isAction;
	// 是否是 被代理
	private boolean isProxy;
	// 本类的代理链
	private Set<BeanKey> proxyList;
	// 构建后执行方法
	private Method postConstruct;
	// 销毁前执行方法
	private Method preDestory;

	// 注入字段【包括依赖对象】
	private List<Field> resourceFields;
	// 依赖对象
	private List<BeanKey> dependences;

	// 事件监听对象
	private Class<? extends ApplicationEvent> eventClass;

	// 针对于@Bean注解
	private BeanKey instanceBean;
	private Method instanceMethod;
	// 构建后执行方法
	private Method initMethod;
	// 销毁前执行方法
	private Method destoryMethod;

	// ====================================

	public Class<?> getBeanClass() {
		return beanKey.getBeanClass();
	}

	public void setBeanKey(BeanKey bk) {
		this.beanKey = bk;
	}

	public BeanKey getBeanKey() {
		return beanKey;
	}

	public EScope getScope() {
		return scope;
	}

	public void setScope(EScope scope) {
		this.scope = scope;
	}

	public List<Field> getResourceFields() {
		return resourceFields;
	}

	public void setResourceFields(Field field) {
		if (resourceFields == null) {
			resourceFields = new ArrayList<>();
		}
		resourceFields.add(field);
	}

	public List<BeanKey> getDependences() {
		return dependences;
	}

	public void setDependences(BeanKey bk) {
		if (dependences == null) {
			dependences = new ArrayList<>();
		}
		this.dependences.add(bk);
	}

	public boolean isTransaction() {
		return isTransaction;
	}

	public void setTransaction(boolean isTransaction) {
		this.isTransaction = isTransaction;
	}

	// public Map<String, Pair<RequestMethod, Method>> getRequestMapping() {
	// return requestMapping;
	// }
	//
	// public void setRequestMapping(String path, RequestMethod rm, Method m) {
	// if (requestMapping == null) {
	// requestMapping = new HashMap<>();
	// }
	// this.requestMapping.put(path, new Pair<RequestMethod, Method>(rm, m));
	// }

	public Method getPostConstruct() {
		return postConstruct;
	}

	public void setPostConstruct(Method postConstruct) {
		this.postConstruct = postConstruct;
	}

	public Method getPreDestory() {
		return preDestory;
	}

	public void setPreDestory(Method preDestory) {
		this.preDestory = preDestory;
	}

	public boolean isLazyInit() {
		return isLazyInit;
	}

	public void setLazyInit(boolean isLazyInit) {
		this.isLazyInit = isLazyInit;
	}

	public BeanKey getInstanceBean() {
		return instanceBean;
	}

	public void setInstanceBean(BeanKey instanceBean) {
		this.instanceBean = instanceBean;
	}

	public Method getInstanceMethod() {
		return instanceMethod;
	}

	public void setInstanceMethod(Method instanceMethod) {
		this.instanceMethod = instanceMethod;
	}

	public Method getInitMethod() {
		return initMethod;
	}

	public void setInitMethod(Method initMethod) {
		this.initMethod = initMethod;
	}

	public Method getDestoryMethod() {
		return destoryMethod;
	}

	public void setDestoryMethod(Method destoryMethod) {
		this.destoryMethod = destoryMethod;
	}

	public Class<? extends ApplicationEvent> getEventClass() {
		return eventClass;
	}

	public void setEventClass(Class<? extends ApplicationEvent> eventClass) {
		this.eventClass = eventClass;
	}

	// public boolean isAction() {
	// return isAction;
	// }
	//
	// public void setAction(boolean isAction) {
	// this.isAction = isAction;
	// }

	public boolean isProxy() {
		return isProxy;
	}

	public void setProxy(boolean isProxy) {
		this.isProxy = isProxy;
	}

	public Set<BeanKey> getProxyList() {
		return proxyList;
	}

	public void addProxyList(BeanKey key) {
		if (proxyList == null)
			proxyList = new HashSet<>();
		if (!Proxy.class.isAssignableFrom(key.getBeanClass())) {
			throw new InitializationError("The ProxyList must be implements Proxy.class");
		}
		setProxy(true);// 当前是个代理类
		proxyList.add(key);
	}

	@Override
	public String toString() {
		return "BeanDefinition [beanKey=" + beanKey + ", scope=" + scope + ", isLazyInit=" + isLazyInit + ", isTransaction=" + isTransaction + ", isProxy=" + isProxy + ", proxyList=" + proxyList + ", postConstruct="
				+ postConstruct + ", preDestory=" + preDestory + ", resourceFields=" + resourceFields + ", dependences=" + dependences + ", eventClass=" + eventClass + ", instanceBean=" + instanceBean
				+ ", instanceMethod=" + instanceMethod + ", initMethod=" + initMethod + ", destoryMethod=" + destoryMethod + "]";
	}

	@Override
	public int compareTo(BeanDefinition obj) {
		return this.getBeanKey().getOrder() - obj.getBeanKey().getOrder();
	}

}
